package com.itheima.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.article.feign.ApAuthorFeign;
import com.itheima.article.pojo.ApAuthor;
import com.itheima.common.constants.BusinessConstants;
import com.itheima.common.enums.HttpCodeEnum;
import com.itheima.common.exception.LeadNewsException;
import com.itheima.common.vo.PageResultVo;
import com.itheima.common.vo.ResultVo;
import com.itheima.user.dto.ApUserRealnamePageRequestDto;
import com.itheima.user.mapper.ApUserMapper;
import com.itheima.user.mapper.ApUserRealnameMapper;
import com.itheima.user.pojo.ApUser;
import com.itheima.user.pojo.ApUserRealname;
import com.itheima.user.service.ApUserRealnameService;
import com.itheima.wemedia.feign.WmUserFeign;
import com.itheima.wemedia.pojo.WmUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Map;

/**
 * @description <p>APP实名认证信息 业务实现</p>
 *
 * @version 1.0
 * @package com.itheima.user.service.impl
 */
@Service
@Slf4j
public class ApUserRealnameServiceImpl extends ServiceImpl<ApUserRealnameMapper, ApUserRealname> implements ApUserRealnameService {
    //注入feign对象
    @Autowired
    private WmUserFeign wmUserFeign;

    @Autowired
    private ApAuthorFeign apAuthorFeign;

    @Autowired
    private ApUserMapper apUserMapper;

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public PageResultVo<ApUserRealname> pageList(ApUserRealnamePageRequestDto dto) {
        //设置分页参数
        IPage<ApUserRealname> pageInfo = new Page(dto.getPage(), dto.getSize());
        //构建查询条件
        LambdaQueryWrapper<ApUserRealname> queryWrapper = new LambdaQueryWrapper<>();

        //查询状态--精确查询
        queryWrapper.eq(null != dto.getStatus(), ApUserRealname::getStatus,dto.getStatus());

        //分页查询
        IPage<ApUserRealname> page = page(pageInfo, queryWrapper);

        return PageResultVo.pageResult(page.getCurrent(),
                page.getSize(),page.getTotal(),page.getRecords());
    }

    /**
     * 实名审核通过
     * @param paramMap
     */
    @Override
    @Transactional(rollbackFor = Throwable.class)
    public void authPass(Map<String, Object> paramMap) {
        //1.参数校验
        Integer id = (Integer) paramMap.get("id");
        log.debug("实名认证：id={}",id);
        if(null == id){
            throw new LeadNewsException(HttpCodeEnum.PARAM_REQUIRE);
        }
        //2.更新实名认证的状态
        ApUserRealname pojo = new ApUserRealname();
        pojo.setId(id.longValue());
        pojo.setUpdatedTime(LocalDateTime.now());
        pojo.setStatus(BusinessConstants.ApUserRealnameConstants.AUTH_PASS);
        updateById(pojo);
        log.debug("实名认证更新认证状态：id={}", id);
        //3. 更新用户信息，认证通过、flag为自媒体人
        // 前端传来的id不是用户的id, 通过查询实名认证信息，得到真正的用户id
        ApUserRealname userRealname = getById(id);
        if(null == userRealname){
            throw new LeadNewsException(HttpCodeEnum.DATA_NOT_EXIST);
        }
        Long appUserId = userRealname.getUserId();
        // 更新用户信息
        ApUser apUser = new ApUser();
        apUser.setId(appUserId);
        // 已经认证过
        apUser.setIsIdentityAuthentication(BusinessConstants.ApUserConstants.AUTHENTICATED);
        // 从普通用户升级为自媒体人
        apUser.setFlag(BusinessConstants.ApUserConstants.FLAG_WEMEDIA);
        log.debug("实名认证，从普通用户升级为自媒体人：id={},appUserId={}",id,appUserId);

        //通过appUserId查询用户
        ApUser apUserInfo = apUserMapper.selectById(appUserId);
        //通过这个id查询自媒体账号，存在即更新，不存在就创建
        Long wmUserId = addWmUser(appUserId,apUserInfo);
        //这里我们已经拥有apUserId和wmUserId，故可以通过这两个id查询作者信息
        //抽取方法添加作者
        addAdAuthor(apUserInfo,wmUserId);
    }

    /**
     * 添加作者
     * @param apUserInfo
     * @param wmUserId
     */
    private void addAdAuthor(ApUser apUserInfo, Long wmUserId) {
        //查询作者是否存在
        //远程调用文章微服务查询
        ResultVo<ApAuthor> result = apAuthorFeign.getByApUserIdAndWmUserId(apUserInfo.getId(), wmUserId);
        //判断是否存在，不存在抛出异常
        if(!result.isSuccess()){
            throw new LeadNewsException("调用微服务查询作者信息失败");
        }
        //获取返回的数据
        ApAuthor apAuthor = result.getData();
        //判断作者信息是否存在
        if(null == apAuthor){
            //新增作者信息
            apAuthor = new ApAuthor();
            apAuthor.setName(apUserInfo.getName());
            apAuthor.setType(BusinessConstants.ApAuthorConstants.A_MEDIA_USER);
            apAuthor.setCreatedTime(LocalDateTime.now());

            apAuthor.setUserId(apUserInfo.getId());
            apAuthor.setWmUserId(wmUserId);
            //远程调用添加方法
            ResultVo resultVo = apAuthorFeign.add(apAuthor);
            //判断是否添加成功
            if(!resultVo.isSuccess()){
                throw new LeadNewsException("远程调用文章微服务添加作者信息失败");
            }

        }
    }

    /**
     * 添加自媒体账号
     * @param appUserId
     * @param apUserInfo
     * @return
     */
    private Long addWmUser(Long appUserId, ApUser apUserInfo) {
        ResultVo<WmUser> wmUserResult = wmUserFeign.getByAppUserId(appUserId);
        if(!wmUserResult.isSuccess()){
            throw new LeadNewsException("调用自媒体微服务失败");
        }
        WmUser wmUser = wmUserResult.getData();
        //判断该对象是否存在，不存在就添加
        if(null == wmUser){
            wmUser = new WmUser();
            BeanUtils.copyProperties(apUserInfo,wmUser);
            //新建的id需要自增，所以设置为null
            wmUser.setId(null);
            wmUser.setApUserId(appUserId);
            wmUser.setNickname(apUserInfo.getName());
            wmUser.setType(BusinessConstants.WmUserConstants.TYPE_PERSONAL);
            wmUser.setStatus(BusinessConstants.WmUserConstants.STATUS_OK);

            wmUser.setCreatedTime(LocalDateTime.now());
            ResultVo<WmUser> wmUserResultVo = wmUserFeign.add(wmUser);
            //判断是否执行成功
            if(!wmUserResultVo.isSuccess()){
                //添加自媒体失败
                throw new LeadNewsException("调用自媒体微服务添加账号失败");
            }
            //此时的id为空
            wmUser = wmUserResultVo.getData();
        }
        return wmUser.getId();
    }

    @Override
    public void authFail(Map<String, Object> paramMap) {
        //获取参数
        Integer keyId = (Integer) paramMap.get("id");
        String reason = (String) paramMap.get("msg");
        //构建更新的对象
        ApUserRealname pojo = new ApUserRealname();
        pojo.setReason(reason);
        pojo.setId(keyId.longValue());

        pojo.setStatus(BusinessConstants.ApUserRealnameConstants.AUTH_REJECT);
        pojo.setUpdatedTime(LocalDateTime.now());
        //更新
        updateById(pojo);
    }
}
